home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 7 / FM Towns Free Software Collection 7.iso / ms_dos / fdu / fdu.c next >
C/C++ Source or Header  |  1993-11-30  |  61KB  |  1,652 lines

  1. /*-------------------------------------------------------------------*/
  2. /*                                                                   */
  3. /*  FDU  (Floppy  Disk  Utility)  Ver. 0.91    */
  4. /*                                                                   */
  5. /*                                             for FM TOWNS or FMR   */
  6. /*                                                                   */
  7. /* Debug Date 930401-930818                                          */
  8. /*                                                                   */
  9. /* Free Ware Collection 7 Release Date      '93-08-18  By T.O6809    */
  10. /*                                                                   */
  11. /*-------------------------------------------------------------------*/
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <malloc.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include <conio.h>
  18. #include <dos.h>
  19. #include <limits.h>
  20. #include <process.h>
  21. #include <io.h>
  22. #include <fcntl.h>
  23.  
  24. #define     VER              "0.91"
  25. #define     DEBUG            0
  26. #define     CSL_OFF()        printf("\x1B[1v")
  27. #define     CSL_ON()         printf("\x1B[0v")
  28. #define     CSL_TOP()        printf("\x1B[80D")
  29. #define     DEL_STR()        printf("\x1B[1K")
  30. #define     COLOR_RED()      printf("\x1B[31m")
  31. #define     COLOR_WHITE()    printf("\x1B[37m")
  32. #define     BEEP()           printf("\x7")
  33.  
  34. #define     MFM              0x00       /* 記録方式                  */
  35. #define     FM               0x80
  36. #define     HD2              0x00       /* FD Type                   */
  37. #define     Hd2              0x50
  38. #define     DD2              0x10
  39. #define     D2               0x20
  40. #define     L0128            0x00       /* Sector Length             */
  41. #define     L0256            0x01
  42. #define     L0512            0x02
  43. #define     L1024            0x03
  44. #define     F640             1
  45. #define     F720             2
  46. #define     F1200            3
  47. #define     F1232            4
  48. #define     F1440            5
  49. #define     FRM              10
  50. #define     FRM_FAT          20
  51. #define     DCP              30
  52. #define     DCP_EMS          31
  53.  
  54. #define     ON               1
  55. #define     OFF              0
  56.  
  57. typedef unsigned long ulong;
  58. typedef unsigned int  uint;
  59. typedef unsigned char uchar;
  60.  
  61. int  drv_cnt = 0;               /* Drive Count                       */
  62. int  drv_media;                 /* 0:FD 1:? 2:HD 3:RAM Disk ff:?     */
  63. int  odno[128];                 /* Drive Number                      */
  64. uint odtp = 0xffff;             /* 1:640k 2:720k 3:1200k 4:1232k     */
  65. uint orpt = 1;                  /* Repeat Count                      */
  66. uint ohlp = 0;                  /* Help Messge                       */
  67. uint odbg = 0;                  /*                                   */
  68. uint obep = 0;                  /*                                   */
  69. uint otyp = 0;                  /* 1:Format 2:Format(FAT) 3:DiskCopy */
  70. uint dtp2;                      /* 1:640k 2:720k 3:1200k 4:1232k     */
  71. uint cc_cnt = 0;                /*                                   */
  72. uint rpt_cnt;                   /*                                   */
  73.  
  74. int  ems_handle;
  75. int  ems_flg = 0;
  76.  
  77. typedef struct {
  78.     uchar   trackno;            /* トラック番号 */
  79.     uchar   headno;             /* ヘッド番号   */
  80.     uchar   secno;              /* セクタ番号   */
  81.     uchar   seclen;             /* セクタ長     */
  82.     uchar   crc1;
  83.     uchar   crc2;
  84. } DKB_SEC;
  85. uchar buf1[13000];
  86.  
  87. static int pr[][15] = {                /* FD Format Information      */
  88. /*    0   1     2    3  4  5  6   7  8  9   10  11 12  13  14*/
  89. /*           SecLenDLenSecTrkHedGap3Gap4Gap0Sync  Gap1Gap2 Byte/Sector*/
  90.      D2,MFM,L0256, 256,16,40, 2, 54,152,80, 12, 96,50, 22,   0,/* 320K 2D FM-7*/
  91.     DD2,MFM,L0512, 512, 8,80, 2, 84,310,80, 12, 96,50, 22, 656,/* 640K 2DD    */
  92.     DD2,MFM,L0512, 512, 9,80, 2, 84,182,80, 12, 96,50, 22, 656,/* 720K 2DD    */
  93.     HD2,MFM,L0512, 512,15,80, 2, 84,400,80, 12, 96,50, 22, 656,/*1200K 2HC    */
  94.     HD2,MFM,L1024,1024, 8,77, 2,116,654,80, 12, 96,50, 22,1200,/*1232K 2HD    */
  95.     Hd2,MFM,L0512, 512,18,80, 2,108,400,80, 12, 96,50, 22, 680,/*1440K 2HD    */
  96.     HD2,MFM,L0256, 256,26,77, 2, 54,598,80, 12, 96,50, 22, 370,/*1-77 8'2D IBM*/
  97.     HD2, FM,L0128, 128,26,77, 2, 27,247,40,  6, 54,20, 11, 186,/*0    8'2D IBM*/
  98. };
  99.  
  100. uchar ipl[][19] = {                    /* FD IPL DATA               */
  101. /*  0 1    2    3    4 5    6    7 8    9    10   11  12 13  14 15  16 17 18 */
  102.     0,0x00,0x00,0x00,0,0x00,0x00,0,0x00,0x00,0x00,0x00,0,0x00,0,0x00,0, 0, 0,
  103.     0,0x02,0x02,0x01,0,0x02,0x70,0,0x00,0x05,0xFB,0x02,0,0x08,0,0x02,0, 0, 0,
  104.     0,0x02,0x02,0x01,0,0x02,0x70,0,0xA0,0x05,0xF9,0x03,0,0x09,0,0x02,0, 0, 0,
  105.     0,0x02,0x01,0x01,0,0x02,0xE0,0,0x60,0x09,0xF9,0x07,0,0x0F,0,0x02,0, 0, 0,
  106.     0,0x04,0x01,0x01,0,0x02,0xC0,0,0xD0,0x04,0xFE,0x02,0,0x08,0,0x02,0, 0, 0,
  107.     0,0x02,0x01,0x01,0,0x02,0xE0,0,0x40,0x0b,0xF0,0x09,0,0x12,0,0x02,0, 0, 0,
  108.     0,0x00,0x00,0x00,0,0x00,0x00,0,0x00,0x00,0x00,0x00,0,0x00,0,0x00,0, 0, 0,
  109.     0,0x00,0x00,0x00,0,0x00,0x00,0,0x00,0x00,0x00,0x00,0,0x00,0,0x00,0, 0, 0,
  110. };
  111. char type[][32] = {
  112.         "F-BASIC       [2D]",
  113.         "MS-DOS(640k  80* 8) [2DD]",
  114.         "MS-DOS(720k  80* 9) [2DD]",
  115.         "MS-DOS(1200k 80*15) [2HC]",
  116.         "MS-DOS(1232k 77* 8) [2HD]",
  117.         "MS-DOS(1440k 80*18) [2HD]",
  118.         "IBM(1-77)    77*26  [8'2D]",
  119.         "IBM(0)       77*26  [8'2D]"
  120. };
  121. int devno[4] = {0x20, 0x21, 0x22, 0x23};/* デバイス番号              */
  122.  
  123. int  chk_opt(int, char *[]);            /* Check Option              */
  124. void err_msg(int, ...);                 /* Error Messge              */
  125. void data_make(void);                   /* Format Data Make          */
  126. void fd_form(void);                     /* FD Format                 */
  127. void fd_form_sub(int);                  /* FD Format Subroutine      */
  128. void init_ipl(int);                     /* FD Initialize IPL Data    */
  129. void fd_form_fat(void);                 /* FD Sector 0 Initialize    */
  130. void init_fat(int);                     /* FD Initialize FAT Data    */
  131. void fd_copy(void);                     /* FD Copy                   */
  132. void fd_copy_sub(int, int);             /* FD Copy Subroutine        */
  133.                                         /* FD_Copy (EMS)             */
  134. void fd_copy_ems(int, int, int, int [], ulong, uchar huge *, int);
  135.                                         /* FD_Copy (Standard Memory) */
  136. void fd_copy_mem(int, int, int, int [], ulong, uchar huge *);
  137. int  ems_alloc(ulong *, int *);         /* EMS Memory Alloc          */
  138. int  ems_chk(void);                     /* EMS Status Check          */
  139. int  ems_map(int far *, int);           /* EMS Map Set               */
  140. int  ems_free(int);                     /* EMS Memory Free           */
  141. void fd_ready1(int);                    /* FD Ready                  */
  142. void fd_ready2(int);                    /* FD Ready                  */
  143. void fd_ready3(int);                    /* FD Ready                  */
  144. void fd_mode_set(int);                  /* FD Mode Stet              */
  145. int  fd_chk(int);                       /* FD Check                  */
  146. void dump(uchar [], int);               /* Dump                      */
  147. void time_get(int *, int *, int *);     /* Timer Get                 */
  148. void interrupt far ctrl_c(void);        /* CTRL+C Interrupt          */
  149. void end_fdu(void);
  150.  
  151.                                         /* Call BIOS Function              */
  152. int  uDKB_setmode(int, uint, uint);                           /* INT 93 00 */
  153. int  uDKB_rdmode(int, uint *, uint *);                        /* INT 93 01 */
  154. int  uDKB_rdstatus(int, uint *);                              /* INT 93 02 */
  155. int  uDKB_restore(int);                                       /* INT 93 03 */
  156. int  uDKB_read(int, int, int, int, int, char *,  int *);      /* INT 93 05 */
  157. int  uDKB_read1(int, int, int, int, int, char huge *,  int *);/* INT 93 05 */
  158. int  uDKB_write(int, int, int, int, int, char *, int *);      /* INT 93 06 */
  159. int  uDKB_write1(int, int, int, int, int, char huge *, int *);/* INT 93 06 */
  160. int  uDKB_chksec(int , int , int , int , int , int *);        /* INT 93 07 */
  161. int  uDKB_rdsecid(int, int, int, DKB_SEC *);                  /* INT 93 09 */
  162. int  uDKB_format(int, int, int, uchar *);                     /* INT 93 0A */
  163. int  system_get(uchar *);                                     /* INT 8E 00 */
  164.  
  165. /*-------------------------------------------------------------------*/
  166. /*                                                                   */
  167. /*-------------------------------------------------------------------*/
  168. int main(int argc, char *argv[])
  169. {
  170.     int   ret;
  171.  
  172.     ret = chk_opt(argc, argv);
  173.     if (ret == 1) {
  174.         err_msg(1);
  175.         exit(1);
  176.     } else if (ret == 2) {
  177.         err_msg(2);
  178.         exit(1);
  179.     }
  180.  
  181.     _dos_setvect(0x23, (void (interrupt far *)())ctrl_c);
  182.  
  183.     CSL_OFF();
  184.  
  185.     switch(otyp) {
  186.         case FRM:                       /* format */
  187.             data_make();
  188.             for (rpt_cnt = 0; rpt_cnt < orpt; rpt_cnt++) {
  189.                 fd_form();
  190.             }
  191.             break;
  192.         case FRM_FAT:                   /* format (FAT) */
  193.             for (rpt_cnt = 0; rpt_cnt < orpt; rpt_cnt++) {
  194.                 fd_form_fat();
  195.             }
  196.             break;
  197.         case DCP:                       /* Disk Copy */
  198.         case DCP_EMS:
  199.             for (rpt_cnt = 0; rpt_cnt < orpt; rpt_cnt++) {
  200.                 fd_copy();
  201.             }
  202.             if (otyp == DCP_EMS) {
  203.                 ems_free(ems_handle);
  204.                 ems_flg = 0;
  205.             }
  206.             break;
  207.         default:
  208.             break;
  209.     }
  210.     /*outp(0x20C, 0x11);
  211.     outp(0x20C, 0x12);*/
  212.     outp(0x208, 0x03);                  /* Motor OFF (bit4 0) */
  213.     CSL_ON();
  214.     return (0);
  215. }
  216.  
  217. /*-------------------------------------------------------------------*/
  218. /*                                                                   */
  219. /*-------------------------------------------------------------------*/
  220. int chk_opt(int ac, char *av[])
  221. {
  222.     int   i, tmp, f_cnt = 0, ret = 0;
  223.     long  wkl;
  224.     uchar machine_sts[200];
  225.  
  226.     if (ac <= 1) {
  227.         ret = 1;
  228.     } else if (av[1][0] == '-' && av[1][1] == '?') {
  229.         ret = 1;
  230.         ohlp = ON;
  231.     } else {
  232.         system_get(&machine_sts[0]);
  233.         for (i = 1; i < ac; i++) {
  234.             if ((av[i][0] >= 'A' && av[i][0] <= 'p' && av[i][1] == ':') ||
  235.                 (av[i][0] >= 'a' && av[i][0] <= 'p' && av[i][1] == ':')  ) {
  236.                 tmp = 0x30 + (toupper(av[i][0]) - 'A') * 2;
  237.                 if ((drv_media = machine_sts[tmp+0]) == 0) {
  238.                     odno[drv_cnt++] = machine_sts[tmp+1];
  239.                 } else {
  240.                     drv_cnt++;
  241.                     ret = 2;
  242.                 }
  243.             } else if (av[i][0] == '-') {
  244.                 if (av[i][1] == 'c' && av[i][2] == (char)NULL) {
  245.                     f_cnt++;
  246.                     otyp = DCP;
  247.                 } else if (av[i][1] == 'c' && av[i][2] == 'c' &&
  248.                            av[i][3] == (char)NULL                ) {
  249.                     f_cnt++;
  250.                     otyp = DCP_EMS;
  251.                 } else if (av[i][1] == 'B') {
  252.                     obep = ON;
  253.                 } else if (av[i][1] == 'f') {
  254.                     f_cnt++;
  255.                     otyp = FRM;
  256.                     if (av[i][2] == (char)NULL) {
  257.                         odtp = F1232;
  258.                     } else if (av[i][3] == (char)NULL) {
  259.                         odtp = av[i][2] - '0';
  260.                         if (!(odtp >= F640 && odtp <= F1440)) {
  261.                             ret = 1;
  262.                         }
  263.                     } else {
  264.                         ret = 1;
  265.                     }
  266.                 } else if (av[i][1] == 'F' && av[i][2] == (char)NULL) {
  267.                     f_cnt++;
  268.                     otyp = FRM_FAT;
  269.                 } else {
  270.                     ret = 1;
  271.                 }
  272.             } else if (av[i][0] == '+') {/* Set Repeat Count */
  273.                 if (isdigit(av[i][1])) {
  274.                     wkl = atol(&av[i][1]);
  275.                     if (wkl == 0 || wkl > UINT_MAX) {
  276.                         ret = 1;
  277.                     } else {
  278.                         orpt = (uint)wkl;
  279.                     }
  280.                 } else {
  281.                     if (av[i][1] == '+' && av[i][2] == (char)NULL) {
  282.                         orpt = UINT_MAX;
  283.                     } else {
  284.                         ret = 1;
  285.                     }
  286.                 }
  287.             } else {
  288.                 ret = 1;
  289.             }
  290.         }
  291.     }
  292.     if (otyp == DCP || otyp == DCP_EMS) {
  293.         if (drv_cnt == 2) {             /* Disk Copy */
  294.             drv_cnt = 1;
  295.         } else {
  296.             ret = 1;
  297.         }
  298.     } else if (otyp ==DCP_EMS && drv_cnt != 1) {
  299.         ret = 1;
  300.     }
  301.     if (drv_cnt == 0) {
  302.         ret = 1;
  303.     }
  304.     if (f_cnt != 1) {
  305.         ret = 1;
  306.     }
  307.  
  308.     return (ret);
  309. }
  310.  
  311. /*-------------------------------------------------------------------*/
  312. /*                                                                   */
  313. /*-------------------------------------------------------------------*/
  314. void err_msg(int msgno, int drv)
  315. {
  316.     if (msgno == 1) {
  317.         if (ohlp == OFF) {
  318.             printf("fdu (Ver. %s)  for FM TOWNS%37cBy T.O6809\n" , VER, ' ');
  319.             puts("Usage: fdu -? | -{f{1-4}|F|c|cc} [-B] [+{+|1-65535}] <Drive:>...");
  320.         } else {
  321.             printf("-- fdu (Ver. %s) -- for FM TOWNS -------"
  322.                    "----------------------- By T.O6809 --\n" , VER);
  323.             puts("Usage: fdu -? | -{f{1-4}|F|c|cc} [-B] [+{+|1-65535}] <Drive:>...");
  324.             puts("----------------------------------------"
  325.                  "---------------------------------------");
  326.             puts("-?          Help");
  327.             puts("-f1         MS-DOS Format  640k[2DD] (80*2* 8* 512*2)");
  328.             puts("-f2         MS-DOS Format  720k[2DD] (80*2* 9* 512*2)");
  329.             puts("-f3         MS-DOS Format 1200k[2HC] (80*2*15* 512*1)");
  330.             puts("-f4         MS-DOS Format 1232k[2HD] (77*2* 8*1024*1)");
  331.             puts("-F          MS-DOS Format FAT Only");
  332.             puts("-c          MS-DOS Disk Copy");
  333.             puts("-cc         MS-DOS Disk Copy (Write FD N times after reading source.)");
  334.             puts("-B          BEEP ON");
  335.             puts("++          65535 Repeat");
  336.             puts("+{1-65535}  1 - 65535 Repeat");
  337.             puts("<Drive:>... A: - P:");
  338.             puts("");
  339.             puts("Ex.)");
  340.             puts("   fdu -f4 +10 a: b:   (format a: and format b:) * 10");
  341.             puts("   fdu -f3 a:          (format /R a:)");
  342.             puts("   fdu -F +5 a:        (format /C a:) * 5");
  343.             puts("   fdu -c +100 a: b:   (diskcopy a: b:) * 100");
  344.             puts("   fdu -c a: a:        (diskcopy a: a:)");
  345.         }
  346.     } else if (msgno == 2) {
  347.         if (drv_media == 2) {
  348.             puts("That is not FD. (Hard Disk)");
  349.         } else if (drv_media == 3) {
  350.             puts("That is not FD. (RAM Disk)");
  351.         } else if (drv_media == 5) {
  352.             puts("That is not FD. (ROM Dvice)");
  353.         } else {
  354.             puts("That is not FD. (Unknow Dvice)");
  355.         }
  356.     } else if (msgno == 3) {
  357.         CSL_TOP();
  358.         printf("%c: Can't format then change anther disk if ready, push any key.",
  359.                'A'+drv);
  360.         getch();
  361.         DEL_STR();
  362.     } else if (msgno == 4) {
  363.         CSL_TOP();
  364.         printf("%c: Unknow format.", 'A'+drv);
  365.     }
  366. }
  367.  
  368. /*-------------------------------------------------------------------*/
  369. /*                                                                   */
  370. /*-------------------------------------------------------------------*/
  371. void data_make(void)
  372. {
  373.     int   cnt, len, i, j, tmp;
  374.  
  375.     for (i = 0; i < pr[odtp][9]; i++) {       /* Gap0            */
  376.         buf1[i] = 0x4E;
  377.     }
  378.     cnt = pr[odtp][9]+pr[odtp][10];
  379.     for (i = pr[odtp][9]; i < cnt; i++) {     /* Sync            */
  380.         buf1[i] = 0;
  381.     }
  382.     if (pr[odtp][1] == MFM) {
  383.         buf1[cnt]   = 0xF6;                   /* Index Mark      */
  384.         buf1[cnt+1] = 0xF6;
  385.         buf1[cnt+2] = 0xF6;
  386.         buf1[cnt+3] = 0xFC;                   /* CRC             */
  387.     } else {
  388.         buf1[cnt]   = 0xFC;                   /* CRC             */
  389.     }
  390.  
  391.     cnt = pr[odtp][11]+pr[odtp][12];
  392.     for (i = pr[odtp][11]; i < cnt; i++) {    /* Gap1            */
  393.         buf1[i] = 0x4E;
  394.     }
  395.  
  396.     for (i = 0; i < pr[odtp][4]; i++) {
  397.         tmp = pr[odtp][14] * i;
  398.         for (j = 0; j < pr[odtp][10]; j++) {  /* Sync            */
  399.             buf1[tmp+cnt+j] = 0;
  400.         }
  401.         len = cnt + pr[odtp][10];
  402.         if (pr[odtp][1] == MFM) {
  403.             buf1[tmp+len++] = 0xF5;           /* ID Address Mark*/
  404.             buf1[tmp+len++] = 0xF5;
  405.             buf1[tmp+len++] = 0xF5;
  406.             buf1[tmp+len++] = 0xFE;
  407.         } else {
  408.             buf1[tmp+len++] = 0xFE;
  409.         }
  410.         buf1[tmp+len++] = 0;                  /* Track   Number  */
  411.         buf1[tmp+len++] = 0;                  /* Cylnder Number  */
  412.         buf1[tmp+len++] = (uchar)(i+1);       /* Sector  Number  */
  413.         buf1[tmp+len++] = (uchar)pr[odtp][2]; /* Sec Len         */
  414.         buf1[tmp+len++] = 0xF7;
  415.  
  416.         for (j = 0; j < pr[odtp][13]; j++) {  /* Gap2            */
  417.             buf1[tmp+len+j] = 0x4E;
  418.         }
  419.         len += pr[odtp][13];
  420.         for (j = 0; j < pr[odtp][10]; j++) {  /* Sync            */
  421.             buf1[tmp+len+j] = 0;
  422.         }
  423.         len += pr[odtp][10];
  424.         if (pr[odtp][1] == MFM) {
  425.             buf1[tmp+len++] = 0xF5;           /* Data or         */
  426.             buf1[tmp+len++] = 0xF5;           /* Deleted DataMark*/
  427.             buf1[tmp+len++] = 0xF5;
  428.             buf1[tmp+len++] = 0xFB;           /* CRC             */
  429.         } else {
  430.             buf1[tmp+len++] = 0xFB;           /* CRC             */
  431.         }
  432.  
  433.         for (j = 0; j < pr[odtp][3]; j++) {   /* Data            */
  434.             buf1[tmp+len+j] = 0xE5;
  435.         }
  436.         len += pr[odtp][3];
  437.         buf1[tmp+len++] = 0xF7;               /* CRC             */
  438.  
  439.         for (j = 0; j < pr[odtp][7]; j++) {   /* Gap3            */
  440.             buf1[tmp+len+j] = 0x4E;
  441.         }
  442.     }
  443.     tmp = pr[odtp][14]*(pr[odtp][4]-1)+len+j;
  444.     for (i = 0; i < pr[odtp][8]*5; i++) {
  445.         buf1[tmp + i] = 0x4E;
  446.     }
  447. }
  448.  
  449. /*-------------------------------------------------------------------*/
  450. /*                                                                   */
  451. /*-------------------------------------------------------------------*/
  452. void fd_form(void)
  453. {
  454.     int ret, i, s_min, s_sec, s_hsec, e_min, e_sec, e_hsec;
  455.     static int f_old = 0xffff;
  456.  
  457.     for (i = 0; i < drv_cnt; i++) {
  458.         if (odno[i] == f_old) {
  459.             CSL_TOP();
  460.             printf("%c: Change disk. [Push Any Key]", 'A'+odno[i]);
  461.             getch();
  462.             DEL_STR();
  463.         }
  464.         f_old = odno[i];
  465.         fd_ready1(odno[i]);
  466.         fd_mode_set(odno[i]);
  467.         CSL_TOP();
  468.         printf("%s Format %c: [%ld/%ld]\n",
  469.                type[odtp], odno[i]+'A', (long)rpt_cnt*drv_cnt+i+1, (long)orpt*drv_cnt);
  470.         while ((ret = fd_chk(odno[i])) != 0) {
  471.             err_msg(3, odno[i]);
  472.         }
  473.         time_get(&s_min, &s_sec, &s_hsec);
  474.  
  475.         fd_form_sub(odno[i]);
  476.         init_ipl(odno[i]);
  477.         init_fat(odno[i]);
  478.  
  479.         time_get(&e_min, &e_sec, &e_hsec);
  480.         if (s_min > e_min) e_min += 60;
  481.         if (s_hsec > e_hsec) {
  482.             e_hsec += 100;
  483.             e_sec--;
  484.         }
  485.         CSL_TOP();
  486.         printf("Finished (%3d.%02d sec)\n",
  487.                (e_min*60 + e_sec) - (s_min*60 + s_sec), e_hsec - s_hsec);
  488.         if (obep == ON) {
  489.             BEEP();
  490.         }
  491.     }
  492. }
  493.  
  494. /*-------------------------------------------------------------------*/
  495. /*                                                                   */
  496. /*-------------------------------------------------------------------*/
  497. void fd_form_sub(int drv)
  498. {
  499.     int  i, j, ret, tmp;
  500.  
  501.     ret = uDKB_restore(devno[drv]);     /* シリンダ0へのシーク      */
  502.  
  503.     CSL_TOP();
  504.     printf("%02d/%02d Track Format", 0, pr[odtp][5]-1);
  505.     tmp = pr[odtp][11]+pr[odtp][12];
  506.     for (i = 0; i < pr[odtp][5]; i++) {
  507.         for (j = 0; j < pr[odtp][4]; j++) { /* Face 0 */
  508.             buf1[pr[odtp][14]*j+tmp+16] = (uchar)i;
  509.             buf1[pr[odtp][14]*j+tmp+17] = 0;
  510.         }
  511.         ret = uDKB_format(devno[drv], i, 0, buf1);
  512.  
  513.         for (j = 0; j < pr[odtp][4]; j++) { /* Face 1 */
  514.             buf1[pr[odtp][14]*j+tmp+17] = 1;
  515.         }
  516.         ret = uDKB_format(devno[drv], i, 1, buf1);
  517.         CSL_TOP();
  518.         printf("%02d", i);
  519.     }
  520. }
  521.  
  522. /*-------------------------------------------------------------------*/
  523. /*                                                                   */
  524. /*-------------------------------------------------------------------*/
  525. void init_ipl(int drv)
  526. {
  527.     int   ret, secnum;
  528.     uchar *bf_p;
  529.  
  530.     bf_p = malloc(pr[odtp][3]*pr[odtp][4]);
  531.     if (bf_p == NULL) {
  532.         puts("Malloc error\n");
  533.         exit(3);
  534.     }
  535.  
  536.     memset(bf_p, 0, pr[odtp][3]*pr[odtp][4]);
  537.     *(bf_p+ 0) = 0xEB;                  /* IPL near jump */
  538.     *(bf_p+ 1) = 0x1C;
  539.     *(bf_p+ 2) = 0x90;
  540.     *(bf_p+ 3) = 0x46;                  /* F */
  541.     *(bf_p+ 4) = 0x44;                  /* D */
  542.     *(bf_p+ 5) = 0x55;                  /* U */
  543.     *(bf_p+ 6) = 0x20;                  /*   */
  544.     *(bf_p+ 7) = 0x30;                  /* 0 */
  545.     *(bf_p+ 8) = 0x2E;                  /* . */
  546.     *(bf_p+ 9) = 0x39;                  /* 9 */
  547.     *(bf_p+10) = 0x31;                  /* 1 */
  548.  
  549.     *(bf_p+11) = ipl[odtp][ 0];         /* Byte/Sector             */
  550.     *(bf_p+12) = ipl[odtp][ 1];
  551.     *(bf_p+13) = ipl[odtp][ 2];         /* Sector/Cluster          */
  552.     *(bf_p+14) = ipl[odtp][ 3];         /* Reserve Sector Number   */
  553.     *(bf_p+15) = ipl[odtp][ 4];
  554.     *(bf_p+16) = ipl[odtp][ 5];         /* FAT Number              */
  555.     *(bf_p+17) = ipl[odtp][ 6];         /* Root Directry Entry MAX */
  556.     *(bf_p+18) = ipl[odtp][ 7];
  557.     *(bf_p+19) = ipl[odtp][ 8];         /* Logical Sector Number   */
  558.     *(bf_p+20) = ipl[odtp][ 9];
  559.     *(bf_p+21) = ipl[odtp][10];         /* Media ID Byte           */
  560.     *(bf_p+22) = ipl[odtp][11];         /* Sector/FAT              */
  561.     *(bf_p+23) = ipl[odtp][12];
  562.     *(bf_p+24) = ipl[odtp][13];         /* Sector/Track            */
  563.     *(bf_p+25) = ipl[odtp][14];
  564.     *(bf_p+26) = ipl[odtp][15];         /* Head                    */
  565.     *(bf_p+27) = ipl[odtp][16];
  566.     *(bf_p+28) = ipl[odtp][17];         /* Hidden Sector           */
  567.     *(bf_p+29) = ipl[odtp][18];
  568.  
  569.     *(bf_p+30) = 0xEA;                  /* IPL Routine             */
  570.     *(bf_p+31) = 0x00;
  571.     *(bf_p+32) = 0x00;
  572.     *(bf_p+33) = 0xFF;
  573.     *(bf_p+34) = 0xFF;
  574.  
  575.     ret = uDKB_write(devno[drv], 0, 0, 1, pr[odtp][4], bf_p, &secnum);
  576.     free(bf_p);
  577. }
  578.  
  579. /*-------------------------------------------------------------------*/
  580. /*                                                                   */
  581. /*-------------------------------------------------------------------*/
  582. void fd_form_fat(void)
  583. {
  584.     int i, s_min, s_sec, s_hsec, e_min, e_sec, e_hsec;
  585.     static uint cnt;
  586.  
  587.     for (i = 0; i < drv_cnt; i++) {
  588.         if (cnt++ != 0) {
  589.             CSL_TOP();
  590.             printf("%c: Change disk. [Push Any Key]", 'A'+odno[i]);
  591.             getch();
  592.             DEL_STR();
  593.         }
  594.         fd_ready1(odno[i]);
  595.         fd_ready2(odno[i]);
  596.         if (odtp == 0xffff) {
  597.             err_msg(4, odno[i]);
  598.             CSL_ON();
  599.             exit(4);
  600.         }
  601.         fd_mode_set(odno[i]);
  602.         CSL_TOP();
  603.         printf("%s Format (FAT) %c: [%ld/%ld]\n",
  604.                type[odtp], odno[i]+'A', (long)rpt_cnt*drv_cnt+i+1, (long)orpt*drv_cnt);
  605.         time_get(&s_min, &s_sec, &s_hsec);
  606.  
  607.         init_fat(odno[i]);
  608.  
  609.         time_get(&e_min, &e_sec, &e_hsec);
  610.         if (s_min > e_min) e_min += 60;
  611.         if (s_hsec > e_hsec) {
  612.             e_hsec += 100;
  613.             e_sec--;
  614.         }
  615.         CSL_TOP();
  616.         printf("Finished (%3d.%02d sec)\n",
  617.                (e_min*60 + e_sec) - (s_min*60 + s_sec), e_hsec - s_hsec);
  618.         if (obep == ON) {
  619.             BEEP();
  620.         }
  621.     }
  622. }
  623.  
  624. /*-------------------------------------------------------------------*/
  625. /*                                                                   */
  626. /*-------------------------------------------------------------------*/
  627. void init_fat(int drv)
  628. {
  629.     int   i, ret, secnum, size1, size2;
  630.     uchar *bf_p;
  631.  
  632.     ret = uDKB_restore(devno[drv]);     /* シリンダ0へのシーク      */
  633.  
  634.     bf_p = malloc(pr[odtp][3]*pr[odtp][4]*2);
  635.     if (bf_p == NULL) {
  636.         puts("Malloc error\n");
  637.         exit(3);
  638.     }
  639.  
  640.     ret = uDKB_read(devno[drv], 0, 0, 1, pr[odtp][4], bf_p, &secnum);
  641.     ret = uDKB_read(devno[drv], 0, 1, 1, pr[odtp][4],
  642.                                 bf_p+pr[odtp][3]*pr[odtp][4], &secnum);
  643.                                         /* FAT Data and Root dir Size */
  644.     size1 = pr[odtp][3]*ipl[odtp][11]*ipl[odtp][5]; /* FAT Total Size */
  645.     size2 = ipl[odtp][6]*32;                        /* Root dir  Size */
  646.     memset(bf_p+pr[odtp][3],          0, size1);
  647.     memset(bf_p+pr[odtp][3]+size1, 0xF6, size2);
  648.     *(bf_p+pr[odtp][3]+0) = ipl[odtp][10];
  649.     *(bf_p+pr[odtp][3]+1) = 0xFF;
  650.     *(bf_p+pr[odtp][3]+2) = 0xFF;
  651.     *(bf_p+pr[odtp][3]+pr[odtp][3]*ipl[odtp][11]+0) = ipl[odtp][10];
  652.     *(bf_p+pr[odtp][3]+pr[odtp][3]*ipl[odtp][11]+1) = 0xFF;
  653.     *(bf_p+pr[odtp][3]+pr[odtp][3]*ipl[odtp][11]+2) = 0xFF;
  654.     for (i = pr[odtp][3]+size1; i < pr[odtp][3]+size1+size2; i += 32) {
  655.         *(bf_p+i) = 0;
  656.     }
  657.     ret = uDKB_write(devno[drv], 0, 0, 1, pr[odtp][4], bf_p+0, &secnum);
  658.     ret = uDKB_write(devno[drv], 0, 1, 1, pr[odtp][4],
  659.                                 bf_p+pr[odtp][3]*pr[odtp][4], &secnum);
  660.     free(bf_p);
  661. }
  662.  
  663. /*-------------------------------------------------------------------*/
  664. /*                                                                   */
  665. /*-------------------------------------------------------------------*/
  666. void fd_copy()
  667. {
  668.     int ret, s_min, s_sec, s_hsec, e_min, e_sec, e_hsec;
  669.  
  670.     if (otyp == DCP && cc_cnt++ != 0) {
  671.         CSL_TOP();
  672.         printf("%c:(src) Change disk. [Push Any Key]", 'A'+odno[0]);
  673.         getch();
  674.         DEL_STR();
  675.     }
  676.  
  677.     if (otyp == DCP || (otyp ==DCP_EMS && cc_cnt == 0)) {
  678.         fd_ready2(odno[0]);                 /* Src         Drive */
  679.         if (odtp == 0xffff) {
  680.             err_msg(4, odno[0]);
  681.             CSL_ON();
  682.             exit(4);
  683.         }
  684.     }
  685.     if (otyp == DCP && odno[0] != odno[1]) {
  686.         fd_ready1(odno[1]);             /* Destination Drive */
  687.     }
  688.     if (otyp == DCP || (otyp ==DCP_EMS && cc_cnt == 0)) {
  689.         data_make();
  690.     }
  691.     fd_mode_set(odno[0]);               /* Src         Drive */
  692.     fd_mode_set(odno[1]);               /* Destination Drive */
  693.     CSL_TOP();
  694.     printf("%s Disk Copy %c: -> %c: [%ld/%ld]\n",
  695.            type[odtp], odno[0]+'A', odno[1]+'A', (long)rpt_cnt+1, (long)orpt*drv_cnt);
  696.     if (otyp == DCP && odno[0] != odno[1]) {
  697.         while ((ret = fd_chk(odno[1])) != 0) {
  698.             err_msg(3, odno[1]);
  699.         }
  700.     }
  701.     time_get(&s_min, &s_sec, &s_hsec);
  702.  
  703.     fd_copy_sub(odno[0], odno[1]);
  704.  
  705.     time_get(&e_min, &e_sec, &e_hsec);
  706.     if (s_min > e_min) e_min += 60;
  707.     if (s_hsec > e_hsec) {
  708.         e_hsec += 100;
  709.         e_sec--;
  710.     }
  711.     CSL_TOP();
  712.     printf("Finished (%3d.%02d sec)\n",
  713.            (e_min*60 + e_sec) - (s_min*60 + s_sec), e_hsec - s_hsec);
  714.     if (obep == ON) {
  715.         BEEP();
  716.     }
  717.     cc_cnt++;
  718. }
  719.  
  720. /*-------------------------------------------------------------------*/
  721. /*                                                                   */
  722. /*-------------------------------------------------------------------*/
  723. void fd_copy_sub(int drv1, int drv2)
  724. {
  725.     ulong  adr;
  726.     int    i, ret, tmp;
  727.     static ulong  bf_max, trk_siz, fd_siz;
  728.     static int   bf_siz[80], loop;
  729.     static uchar huge *bf_p;
  730.  
  731.     trk_siz = pr[odtp][3] * pr[odtp][4];
  732.     fd_siz  = trk_siz * pr[odtp][5] * 2;
  733.  
  734.     if ((otyp == DCP && drv1 == drv2) || (otyp == DCP_EMS && cc_cnt == 0)) {
  735.         if (ems_chk() == 0) {
  736.             if ((ems_alloc(&adr, &ems_handle)) == 0) {
  737.                 ems_flg = 1;
  738.                 bf_p = (uchar huge *)adr;
  739.                 bf_max = 16L*1024*4;
  740.             }
  741.         }
  742.     }
  743.     if (otyp == DCP_EMS && ems_flg == 0) {
  744.         printf("No enough EMS, then option \"-cc\" can't use.");
  745.         end_fdu();
  746.         exit(3);
  747.     }
  748.     if (ems_flg == 0) {
  749.         for (bf_max = 0xA0000; bf_max > 0; bf_max -= trk_siz) {
  750.             bf_p = (uchar huge *)halloc(bf_max, sizeof(char));
  751.             if (bf_p != NULL) {
  752.                 break;
  753.             }
  754.         }
  755.     }
  756.  
  757.     if ((otyp == DCP_EMS && cc_cnt == 0)|| otyp == DCP) {
  758.         tmp = (uint)(bf_max / (trk_siz*2));
  759.         loop = pr[odtp][5] / tmp;
  760.         for (i = 0; i < loop; i++) {
  761.             bf_siz[i] = tmp;
  762.         }
  763.         if ((pr[odtp][5] % tmp) != 0) {
  764.             bf_siz[loop++] = (pr[odtp][5] % tmp);
  765.         }
  766.     }
  767.     ret = uDKB_restore(devno[drv1]);     /* シリンダ0へのシーク */
  768.     ret = uDKB_restore(devno[drv2]);     /* シリンダ0へのシーク */
  769.  
  770.     if (ems_flg == 1) {
  771.         fd_copy_ems(drv1, drv2, loop, bf_siz, trk_siz, bf_p, ems_handle);
  772.     } else {
  773.         fd_copy_mem(drv1, drv2, loop, bf_siz, trk_siz, bf_p);
  774.     }
  775.  
  776.     if (ems_flg == 1) {
  777.         if (otyp == DCP) {
  778.             ems_free(ems_handle);
  779.             ems_flg = 0;
  780.         }
  781.     } else {
  782.         hfree(bf_p);
  783.     }
  784. }
  785.  
  786. /*-------------------------------------------------------------------*/
  787. /*                                                                   */
  788. /*-------------------------------------------------------------------*/
  789. void fd_copy_ems(int drv1, int drv2, int loop, int bf_siz[], 
  790.                  ulong trk_siz, uchar huge *bf_p, int handle)
  791. {
  792.     int  i, j, k, l;
  793.     int  ret, secnum, tmp, track, page, rcnt = 0, ret1, ret2, dtp;
  794.     uint far *map_adr;
  795.     uint map_data[4*2];
  796.  
  797.     if ((otyp == DCP && drv1 == drv2) || (otyp == DCP_EMS && cc_cnt == 0)) {
  798.         for (i = 0, page = 0, track = 0; i < loop; i++) {
  799.             for (j = 0; j < 4; j++) {
  800.                 map_data[j*2]   = page++;
  801.                 map_data[j*2+1] = j;
  802.             }
  803.             map_adr = map_data;
  804.             ems_map(map_adr, handle);
  805.             for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
  806.                 CSL_TOP();
  807.                 printf("%02d/%02d Track Read  ", j, pr[odtp][5]-1);
  808.                 while (1) {
  809.                     rcnt++;
  810.                     ret = uDKB_read1(devno[drv1], j, 0, 1,pr[odtp][4],
  811.                                      bf_p+k*trk_siz*2, &secnum);
  812.                     if (ret == 0) {
  813.                         rcnt = 0;
  814.                         break;
  815.                     } else if (rcnt >= 2) {
  816.                         printf("Read error [%x]", ret);
  817.                         end_fdu();
  818.                         exit(2);
  819.                     }
  820.                 }
  821.                 while (1) {
  822.                     rcnt++;
  823.                     ret = uDKB_read1(devno[drv1], j, 1, 1,pr[odtp][4],
  824.                                      bf_p+k*trk_siz*2+trk_siz, &secnum);
  825.                     if (ret == 0) {
  826.                         rcnt = 0;
  827.                         break;
  828.                     } else if (rcnt >= 2) {
  829.                         printf("Read error [%x]", ret);
  830.                         end_fdu();
  831.                         exit(2);
  832.                     }
  833.                 }
  834.             }
  835.             track += bf_siz[i];
  836.         }
  837.     }
  838.  
  839.     if (drv1 == drv2 || (otyp == DCP_EMS && cc_cnt != 0)) {
  840.         CSL_TOP();
  841.         printf("%c:(dst) Change disk. [Push Any Key]", 'A'+drv2);
  842.         getch();
  843.         DEL_STR();
  844.     }
  845.     fd_ready1(drv2);                    /* Destination Drive */
  846.     while ((ret = fd_chk(drv2)) != 0) {
  847.         err_msg(3, drv2);
  848.         fd_ready1(drv2);                /* Destination Drive */
  849.     }
  850.  
  851.     tmp = pr[odtp][11]+pr[odtp][12];
  852.     for (i = 0, page = 0, track = 0; i < loop; i++) {
  853.         for (j = 0; j < 4; j++) {
  854.             map_data[j*2]   = page++;
  855.             map_data[j*2+1] = j;
  856.         }
  857.         map_adr = map_data;
  858.         ems_map(map_adr, handle);
  859.         for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
  860.             dtp = dtp2;
  861.             rcnt = 0;
  862.             while (1) {
  863.                 rcnt++;
  864.                 if (odtp != dtp2) {
  865.                     CSL_TOP();
  866.                     printf("%02d/%02d Track Format", j, pr[odtp][5]-1);
  867.                     for (l = 0; l < pr[odtp][4]; l++) {  /* Face 0 */
  868.                         buf1[pr[odtp][14]*l+tmp+16] = (uchar)j;
  869.                         buf1[pr[odtp][14]*l+tmp+17] = 0;
  870.                     }
  871.                     ret = uDKB_format(devno[drv2], j, 0, buf1);
  872.                     for (l = 0; l < pr[odtp][4]; l++) {  /* Face 1 */
  873.                         buf1[pr[odtp][14]*l+tmp+17] = 1;
  874.                     }
  875.                     ret = uDKB_format(devno[drv2], j, 1, buf1);
  876.                 }
  877.                 CSL_TOP();
  878.                 printf("%02d/%02d Track Write ", j, pr[odtp][5]-1);
  879.                 ret1 = uDKB_write1(devno[drv2], j, 0, 1,pr[odtp][4],
  880.                                   bf_p+k*trk_siz*2, &secnum);
  881.                 ret2 = uDKB_write1(devno[drv2], j, 1, 1,pr[odtp][4],
  882.                                   bf_p+k*trk_siz*2+trk_siz, &secnum);
  883.                 if (ret1 == 0 && ret2 == 0) {
  884.                     dtp2 = dtp;
  885.                     break;
  886.                 } else if (rcnt >= 2) {
  887.                     printf("Write error ");
  888.                     end_fdu();
  889.                     exit(2);
  890.                 } else {
  891.                     dtp2 = !odtp;
  892.                 }
  893.             }
  894.         }
  895.         track += bf_siz[i];
  896.     }
  897. }
  898.  
  899. /*-------------------------------------------------------------------*/
  900. /*                                                                   */
  901. /*-------------------------------------------------------------------*/
  902. void fd_copy_mem(int drv1, int drv2, int loop, int *bf_siz,
  903.                  ulong trk_siz, uchar huge *bf_p)
  904. {
  905.     int  i, j, k, l;
  906.     int  ret, secnum, tmp, track, rcnt = 0, ret1, ret2, dtp;
  907.  
  908.     for (i = 0, track = 0; i < loop; i++) {
  909.         if (drv1 == drv2 && i != 0) {
  910.             CSL_TOP();
  911.             printf("%c:(dst) Change disk. [Push Any Key]", 'A'+drv1);
  912.             getch();
  913.             DEL_STR();
  914.             fd_ready3(drv1);            /* Destination or Src Drive */
  915.         }
  916.         for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
  917.             CSL_TOP();
  918.             printf("%02d/%02d Track Read  ", j, pr[odtp][5]-1);
  919.             while (1) {
  920.                 rcnt++;
  921.                 ret = uDKB_read1(devno[drv1], j, 0, 1,pr[odtp][4],
  922.                                  bf_p+k*trk_siz*2, &secnum);
  923.                 if (ret == 0) {
  924.                     rcnt = 0;
  925.                     break;
  926.                 } else if (rcnt >= 2) {
  927.                     printf("Read error [%x]", ret);
  928.                     end_fdu();
  929.                     exit(2);
  930.                 }
  931.             }
  932.             while (1) {
  933.                 rcnt++;
  934.                 ret = uDKB_read1(devno[drv1], j, 1, 1,pr[odtp][4],
  935.                                  bf_p+k*trk_siz*2+trk_siz, &secnum);
  936.                 if (ret == 0) {
  937.                     rcnt = 0;
  938.                     break;
  939.                 } else if (rcnt >= 2) {
  940.                     printf("Read error [%x]", ret);
  941.                     end_fdu();
  942.                     exit(2);
  943.                 }
  944.             }
  945.         }
  946.  
  947.         if (drv1 == drv2) {
  948.             CSL_TOP();
  949.             printf("%c:(dst) Change disk. [Push Any Key]", 'A'+drv2);
  950.             getch();
  951.             DEL_STR();
  952.             fd_ready1(drv2);            /* Destination Drive */
  953.             if (i == 0) {
  954.                 printf("");
  955.                 while ((ret = fd_chk(drv2)) != 0) {
  956.                     err_msg(3, drv2);
  957.                     fd_ready1(drv2);    /* Destination Drive */
  958.                 }
  959.             }
  960.         } else if (i == 0 && otyp == DCP_EMS) {
  961.             dtp2 = odtp;
  962.         }
  963.         tmp = pr[odtp][11]+pr[odtp][12];
  964.         for (j = track, k = 0; j < track+bf_siz[i]; j++, k++) {
  965.             dtp = dtp2;
  966.             rcnt = 0;
  967.             while (1) {
  968.                 rcnt++;
  969.                 if (odtp != dtp2) {
  970.                     CSL_TOP();
  971.                     printf("%02d/%02d Track Format", j, pr[odtp][5]-1);
  972.                     for (l = 0; l < pr[odtp][4]; l++) {  /* Face 0 */
  973.                         buf1[pr[odtp][14]*l+tmp+16] = (uchar)j;
  974.                         buf1[pr[odtp][14]*l+tmp+17] = 0;
  975.                     }
  976.                     ret = uDKB_format(devno[drv2], j, 0, buf1);
  977.                     for (l = 0; l < pr[odtp][4]; l++) {  /* Face 1 */
  978.                         buf1[pr[odtp][14]*l+tmp+17] = 1;
  979.                     }
  980.                     ret = uDKB_format(devno[drv2], j, 1, buf1);
  981.                 }
  982.                 CSL_TOP();
  983.                 printf("%02d/%02d Track Write ", j, pr[odtp][5]-1);
  984.                 ret1 = uDKB_write1(devno[drv2], j, 0, 1,pr[odtp][4],
  985.                                   bf_p+k*trk_siz*2, &secnum);
  986.                 ret2 = uDKB_write1(devno[drv2], j, 1, 1,pr[odtp][4],
  987.                                   bf_p+k*trk_siz*2+trk_siz, &secnum);
  988.                 if (ret1 == 0 && ret2 == 0) {
  989.                     dtp2 = dtp;
  990.                     break;
  991.                 } else if (rcnt >= 2) {
  992.                     printf("Write error ");
  993.                     end_fdu();
  994.                     exit(2);
  995.                 } else {
  996.                     dtp2 = !odtp;
  997.                 }
  998.             }
  999.         }
  1000.         track += bf_siz[i];
  1001.     }
  1002. }
  1003.  
  1004. /*-------------------------------------------------------------------*/
  1005. /*                                                                   */
  1006. /*-------------------------------------------------------------------*/
  1007. int ems_chk(void)
  1008. {
  1009.     union  REGS inregs, outregs;
  1010.     char ver[4];
  1011.     int  ret = 1, ret1, fhdl;
  1012.                                         /* EMSの常駐の確認 */
  1013.     if ((fhdl = open("EMMXXXX0", O_RDONLY)) != -1) {
  1014.         inregs.x.ax = 0x4400;
  1015.         inregs.x.bx = fhdl;
  1016.         intdos(&inregs, &outregs);
  1017.         if ((outregs.x.dx & 0x0080) != 0) { /* Device or File ? */
  1018.             inregs.h.ah = 0x40;
  1019.             int86(0x67, &inregs, &outregs);
  1020.             if (outregs.h.ah == 0) {        /* Get Status */
  1021.                 inregs.h.ah = 0x46;
  1022.                 int86(0x67, &inregs, &outregs);
  1023.                 if (outregs.h.ah == 0) {    /* Get Version */
  1024.                     if (outregs.h.al >= 0x40) {
  1025.                         ret = 0;
  1026.                     }
  1027.                 }
  1028.             }
  1029.         }
  1030.     }
  1031.     return(ret);
  1032. }
  1033.  
  1034. /*-------------------------------------------------------------------*/
  1035. /*                                                                   */
  1036. /*-------------------------------------------------------------------*/
  1037. int ems_alloc(ulong *adr, int *handle)
  1038. {
  1039.     union  REGS inregs, outregs;
  1040.     struct SREGS segregs;
  1041.     uint i;
  1042.     int  ret = 1, tmp;
  1043.     int  free_page, alloc_page;
  1044.     static uint map[256];
  1045.     static uint far *p;
  1046.  
  1047.     while (1) {
  1048.         inregs.h.ah = 0x42;
  1049.         int86(0x67, &inregs, &outregs); /* Get Uballocated Page Count */
  1050.         if (outregs.h.ah != 0) {
  1051.             break;
  1052.         }
  1053.         free_page = outregs.x.bx;
  1054.         tmp = (16*4)/((pr[odtp][3]*pr[odtp][4]*2)/1024);
  1055.         alloc_page = pr[odtp][5] * 4 / tmp;
  1056.         if ((tmp = alloc_page % 4) != 0) {
  1057.             alloc_page+=(4-tmp);
  1058.         }
  1059.         if (free_page < alloc_page) {
  1060.             break;
  1061.         }
  1062.         inregs.h.ah = 0x43;
  1063.         inregs.x.bx = alloc_page;
  1064.         int86(0x67, &inregs, &outregs); /* Allocated Pages */
  1065.         if (outregs.h.ah != 0) {
  1066.             break;
  1067.         }
  1068.         *handle = outregs.x.dx;
  1069.         inregs.h.ah = 0x41;     
  1070.         int86(0x67, &inregs, &outregs); /* Get Page Frame Address */
  1071.         if (outregs.h.ah != 0) {
  1072.             break;
  1073.         }
  1074.         *adr = ((ulong)outregs.x.bx << 16);
  1075.         p = map;
  1076.         inregs.x.ax = 0x5800;
  1077.         segregs.es  = FP_SEG(p);
  1078.         inregs.x.di = FP_OFF(p);        /* Get Mappable Physical Address Array */
  1079.         int86x(0x67, &inregs, &outregs, &segregs);
  1080.         if (outregs.x.cx < 4 && outregs.h.ah != 0) {
  1081.             break;
  1082.         }
  1083.         for (i = 0; i < outregs.x.cx; i++) {
  1084.             if (map[i*2] == (uint)(*adr>>16)) {
  1085.                 if (map[i*2+1]     == 0 && map[(i+1)*2+1] == 1 &&
  1086.                     map[(i+2)*2+1] == 2 && map[(i+3)*2+1] == 3   ) {
  1087.                     ret = 0;
  1088.                     break;
  1089.                 }
  1090.             }
  1091.         }
  1092.         break;
  1093.     }
  1094.     return(ret);
  1095. }
  1096.  
  1097. /*-------------------------------------------------------------------*/
  1098. /*                                                                   */
  1099. /*-------------------------------------------------------------------*/
  1100. int ems_map(int far *map, int handle)
  1101. {
  1102.     union  REGS inregs, outregs;
  1103.     struct SREGS segregs;
  1104.     int    ret = 0;
  1105.  
  1106.     inregs.x.ax = 0x5000;               /* Map Multiple Pages */
  1107.     inregs.x.dx = handle;
  1108.     inregs.x.cx = 4;
  1109.     segregs.ds  = FP_SEG(map);
  1110.     inregs.x.si = FP_OFF(map);
  1111.     int86x(0x67, &inregs, &outregs, &segregs);
  1112.     if (outregs.h.ah != 0) {
  1113.         printf("ems_map err(%02x)\n", outregs.h.ah);
  1114.         ret = 1;
  1115.     }
  1116.     return (ret);
  1117. }
  1118.  
  1119. /*-------------------------------------------------------------------*/
  1120. /*                                                                   */
  1121. /*-------------------------------------------------------------------*/
  1122. int ems_free(int handle)
  1123. {
  1124.     union  REGS inregs, outregs;
  1125.     int  ret = 0;
  1126.  
  1127.     inregs.h.ah = 0x45;                 /* Deallocate Pages */
  1128.     inregs.x.dx = handle;
  1129.     int86(0x67, &inregs, &outregs);
  1130.     if (outregs.h.ah != 0) {
  1131.         ret = 1;
  1132.     }
  1133.     return (ret);
  1134. }
  1135.  
  1136. /*-------------------------------------------------------------------*/
  1137. /*                                                                   */
  1138. /*-------------------------------------------------------------------*/
  1139. void fd_ready1(int drv)
  1140. {
  1141.     uint status;
  1142.     int  ret;
  1143.  
  1144.     while (1) {
  1145.         ret = uDKB_rdstatus(devno[drv], &status);
  1146.         if ((status & 0x01) != 0) {
  1147.             CSL_TOP();
  1148.             printf("%c: Disk device ready? [Push Any Key]", 'A'+drv);
  1149.             getch();
  1150.             DEL_STR();
  1151.         } else if ((status & 0x02) != 0) {
  1152.             CSL_TOP();
  1153.             printf("%c: Can't write then push any key after release it's protect.",
  1154.                    'A'+drv);
  1155.             getch();
  1156.             DEL_STR();
  1157.         } else {
  1158.             break;
  1159.         }
  1160.     }
  1161. }
  1162.  
  1163. /*-------------------------------------------------------------------*/
  1164. /*                                                                   */
  1165. /*-------------------------------------------------------------------*/
  1166. void fd_ready2(int drv)
  1167. {
  1168.     uint  status;
  1169.     int   i, ret, secnum;
  1170.     DKB_SEC secid;
  1171.     uchar bf[1024];
  1172.  
  1173.     while (1) {
  1174.         ret = uDKB_rdstatus(devno[drv], &status);
  1175.         if ((status & 0x01) != 0) {
  1176.             CSL_TOP();
  1177.             printf("%c: Drive ready? [Push Any Key]", 'A'+drv);
  1178.             getch();
  1179.             DEL_STR();
  1180.         } else {
  1181.             break;
  1182.         }
  1183.     }
  1184.     odtp = 0xffff;
  1185.                                         /* odtp set */
  1186.     if ((ret = uDKB_rdsecid(devno[drv], 0, 0, &secid)) == 0) {
  1187.         for (i = 0; i < 7; i++) {
  1188.             if ((uint)(pr[i][0] | pr[i][1]) == (status & 0x00F0)) {
  1189.                 if (secid.seclen == (uchar)pr[i][2]) {
  1190.                     odtp = i;
  1191.                     break;
  1192.                 }
  1193.             }
  1194.         }
  1195.         if (odtp == 1) {
  1196.             ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
  1197.             if (bf[0x18] == 9) {
  1198.                 odtp = F720;
  1199.             }
  1200.         } else if (odtp == F1200) {
  1201.             ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
  1202.             if (bf[0x18] != 0x0f) {
  1203.                 odtp = 0xffff;
  1204.             }
  1205.         }
  1206.     }
  1207. }
  1208.  
  1209. /*-------------------------------------------------------------------*/
  1210. /*                                                                   */
  1211. /*-------------------------------------------------------------------*/
  1212. void fd_ready3(int drv)
  1213. {
  1214.     uint status;
  1215.     int  ret;
  1216.  
  1217.     while (1) {
  1218.         ret = uDKB_rdstatus(devno[drv], &status);
  1219.         if ((status & 0x01) != 0) {
  1220.             CSL_TOP();
  1221.             printf("%c: Drive ready? [Push Any Key]", 'A'+drv);
  1222.             getch();
  1223.             DEL_STR();
  1224.         } else {
  1225.             break;
  1226.         }
  1227.     }
  1228. }
  1229.  
  1230. /*-------------------------------------------------------------------*/
  1231. /*                                                                   */
  1232. /*-------------------------------------------------------------------*/
  1233. void fd_mode_set(int drv)
  1234. {
  1235.     int  ret;
  1236.     uint mode1, mode2;
  1237.  
  1238.     mode1 = pr[odtp][0] | pr[odtp][1] | pr[odtp][2];
  1239.     mode2 = (pr[odtp][6] << 8) | pr[odtp][4];
  1240.     ret = uDKB_setmode(devno[drv], mode1, mode2);
  1241. }
  1242.  
  1243. /*-------------------------------------------------------------------*/
  1244. /*                                                                   */
  1245. /*-------------------------------------------------------------------*/
  1246. int fd_chk(int drv)
  1247. {
  1248.     int   i, ret = 0, ret1 = 0, ret2 = 0, ret3 = 0;
  1249.     int   secnum, tmp;
  1250.     uchar bf[1024];
  1251.     uint  status;
  1252.     DKB_SEC secid;
  1253.  
  1254.     dtp2 = 0xffff;
  1255.     if (otyp != FRM) {
  1256.         if ((ret = uDKB_rdstatus(devno[drv], &status))     == 0 &&
  1257.             (ret = uDKB_rdsecid(devno[drv], 0, 0, &secid)) == 0   ) {
  1258.             for (i = 0; i < 7; i++) {
  1259.                 if ((uint)(pr[i][0] | pr[i][1]) == (status & 0x00F0)) {
  1260.                     if (secid.seclen == (uchar)pr[i][2]) {
  1261.                         dtp2 = i;
  1262.                         break;
  1263.                     }
  1264.                 }
  1265.             }
  1266.             if (dtp2 == F640) {
  1267.                 ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
  1268.                 if (bf[0x18] == 9) {
  1269.                     dtp2 = F720;
  1270.                 }
  1271.             } else if (dtp2 == F1200) {
  1272.                 ret = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
  1273.                 if (bf[0x18] != 0x0f) {
  1274.                     dtp2 = 0xffff;
  1275.                 }
  1276.             }
  1277.         }
  1278.     }
  1279.     if (dtp2 != odtp) {
  1280.         fd_mode_set(drv);
  1281.         ret = uDKB_restore(devno[drv]); /* シリンダ0へのシーク */
  1282.         tmp = pr[odtp][11]+pr[odtp][12];
  1283.         for (i = 0; i < pr[odtp][4]; i++) {
  1284.             buf1[pr[odtp][14]*i+tmp+16] = 0;
  1285.             buf1[pr[odtp][14]*i+tmp+17] = 0;
  1286.         }
  1287.         ret1 = uDKB_format(devno[drv], 0, 0, buf1);
  1288.         ret2 = uDKB_chksec(devno[drv], 0, 0, 1, 1, &secnum);
  1289.         ret3 = uDKB_read(devno[drv], 0, 0, 1, 1, &bf[0], &secnum);
  1290.     }
  1291.  
  1292.     if (!(ret1 == 0 && ret2 == 0 && ret3 == 0)) {
  1293.         ret = 1;
  1294.     } else {
  1295.         ret = 0;
  1296.     }
  1297.  
  1298.     return(ret);
  1299. }
  1300.  
  1301. /*-------------------------------------------------------------------*/
  1302. /*                                                                   */
  1303. /*-------------------------------------------------------------------*/
  1304. void dump(uchar bf[], int size)
  1305. {
  1306.     int   cnt = 0, i, j;
  1307.  
  1308.     do {
  1309.         printf ("XXXX:%04X ", cnt*16);
  1310.         for (i = 0; i < 16; i++) {
  1311.             if (i == 8) {
  1312.                 printf("-");
  1313.                 printf("%02X", bf[(cnt*16)+i]);
  1314.             } else {
  1315.                 printf(" %02X", bf[(cnt*16)+i]);
  1316.             }
  1317.         }
  1318.         printf("  ");
  1319.         for (j = 0; j < 16; j++) {
  1320.             if (!(bf[(cnt*16)+j] >= 0x20 && bf[(cnt*16)+j] <= 0x7e)) {
  1321.                 printf(".");
  1322.             } else {
  1323.                 printf ("%c", bf[(cnt*16)+j]);
  1324.             }
  1325.         }
  1326.         printf("\n");
  1327.         cnt++;
  1328.     } while (cnt*16 < size);
  1329. }
  1330.  
  1331. /*-------------------------------------------------------------------*/
  1332. /*                                                                   */
  1333. /*-------------------------------------------------------------------*/
  1334. void time_get(int *min, int *sec, int *hsec)
  1335. {
  1336.     union  REGS  inregs, outregs;
  1337.  
  1338.     inregs.h.ah = 0x2c;
  1339.     intdos(&inregs, &outregs);
  1340.     *min  = outregs.h.cl;
  1341.     *sec  = outregs.h.dh;
  1342.     *hsec = outregs.h.dl;
  1343. }
  1344.  
  1345. /*-------------------------------------------------------------------*/
  1346. /*  CTRL+C Interrupt Routine                                         */
  1347. /*-------------------------------------------------------------------*/
  1348. void interrupt far ctrl_c(void)
  1349. {
  1350.     end_fdu();
  1351.     exit(5);
  1352. }
  1353.  
  1354. /*-------------------------------------------------------------------*/
  1355. /*                                                                   */
  1356. /*-------------------------------------------------------------------*/
  1357. void end_fdu(void)
  1358. {
  1359.     static union  REGS inregs, outregs;
  1360.  
  1361.     if (ems_flg == 1) {
  1362.         inregs.h.ah = 0x45;             /* 使用領域の解放 */
  1363.         inregs.x.dx = ems_handle;
  1364.         int86(0x67, &inregs, &outregs);
  1365.     }
  1366.  
  1367.     COLOR_RED();
  1368.     printf("Abnormal stop");
  1369.     COLOR_WHITE();
  1370.     CSL_ON();
  1371. }
  1372.  
  1373. /*-------------------------------------------------------------------*/
  1374. /* ドライブモードの設定  (FD)                                        */
  1375. /*-------------------------------------------------------------------*/
  1376. int uDKB_setmode(int devno, uint mode1, uint mode2)
  1377. {
  1378.     union  REGS  inregs, outregs;
  1379.     int    ret;
  1380.  
  1381.     inregs.h.ah = 0x00;                 /* 機能コード   */
  1382.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1383.     inregs.h.dl = (uchar)mode1;         /* ドライブモード1 */
  1384.     inregs.x.bx = mode2;                /* ドライブモード2 */
  1385.     int86(0x93, &inregs, &outregs);
  1386.     ret = outregs.h.ah;
  1387.  
  1388.     return (ret);
  1389. }
  1390.  
  1391. /*-------------------------------------------------------------------*/
  1392. /*  ドライブモードの取り出し  (FD)                                   */
  1393. /*-------------------------------------------------------------------*/
  1394. int uDKB_rdmode(int devno, uint *mode1, uint *mode2)
  1395. {
  1396.     union  REGS  inregs, outregs;
  1397.     int    ret;
  1398.  
  1399.     inregs.h.ah = 0x01;                 /* 機能コード   */
  1400.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1401.     int86(0x93, &inregs, &outregs);
  1402.     *mode1 = outregs.h.dl;              /* ドライブモード1 */
  1403.     *mode2 = outregs.x.bx;              /* ドライブモード2 */
  1404.     ret = outregs.h.ah;
  1405.  
  1406.     return (ret);
  1407. }
  1408.  
  1409. /*-------------------------------------------------------------------*/
  1410. /* ドライブステータ情報の取り出し  (FD)                              */
  1411. /*-------------------------------------------------------------------*/
  1412. int uDKB_rdstatus(int devno, uint *status)
  1413. {
  1414.     union  REGS  inregs, outregs;
  1415.     int    ret;
  1416.  
  1417.     inregs.h.ah = 0x02;                 /* 機能コード   */
  1418.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1419.     inregs.h.ch = 0x00;                 /*              */
  1420.     int86(0x93, &inregs, &outregs);
  1421.     *status = outregs.h.dl;
  1422.     ret = outregs.h.ah;
  1423.     if (ret == 0x80) {
  1424.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1425.     }
  1426.  
  1427.     return (ret);
  1428. }
  1429.  
  1430. /*-------------------------------------------------------------------*/
  1431. /* シリンダ0へのシーク  (FD)                                        */
  1432. /*-------------------------------------------------------------------*/
  1433. int uDKB_restore(int devno)
  1434. {
  1435.     union  REGS  inregs, outregs;
  1436.     int    ret;
  1437.  
  1438.     inregs.h.ah = 0x03;             /* 機能コード   */
  1439.     inregs.h.al = (uchar)devno;     /* デバイス番号 */
  1440.     inregs.x.cx = 0x00;
  1441.     int86(0x93, &inregs, &outregs);
  1442.     ret = outregs.h.ah;
  1443.     if (ret == 0x80) {
  1444.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1445.     }
  1446.  
  1447.     return (ret);
  1448. }
  1449.  
  1450. /*-------------------------------------------------------------------*/
  1451. /*  データの読み込み  (FD)                                           */
  1452. /*-------------------------------------------------------------------*/
  1453. int uDKB_read(int  devno, int cylno, int headno, int secno, int seccnt,
  1454.               char *buf1,  int *secnum)
  1455. {
  1456.     union  REGS  inregs, outregs;
  1457.     struct SREGS segregs;
  1458.     int    ret;
  1459.  
  1460.     inregs.h.ah = 0x05;                 /* 機能コード   */
  1461.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1462.     inregs.x.cx = cylno;                /* シリンダ番号 */
  1463.     inregs.h.dh = (uchar)headno;        /* ベッド番号   */
  1464.     inregs.h.dl = (uchar)secno;         /* セクタ番号   */
  1465.     inregs.x.bx = seccnt;               /* セクタ数     */
  1466.     segread(&segregs);
  1467.     inregs.x.di = FP_OFF(buf1);
  1468.     int86x(0x93, &inregs, &outregs, &segregs);
  1469.     *secnum = outregs.x.bx;
  1470.     ret = outregs.h.ah;
  1471.     if (ret == 0x80) {
  1472.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1473.     }
  1474.  
  1475.     return (ret);
  1476. }
  1477.  
  1478. /*-------------------------------------------------------------------*/
  1479. /*  データの読み込み  (FD)                                           */
  1480. /*-------------------------------------------------------------------*/
  1481. int uDKB_read1(int  devno, int cylno, int headno, int secno, int seccnt,
  1482.               char huge *buf1,  int *secnum)
  1483. {
  1484.     union  REGS  inregs, outregs;
  1485.     struct SREGS segregs;
  1486.     int    ret;
  1487.  
  1488.     inregs.h.ah = 0x05;                 /* 機能コード   */
  1489.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1490.     inregs.x.cx = cylno;                /* シリンダ番号 */
  1491.     inregs.h.dh = (uchar)headno;        /* ベッド番号   */
  1492.     inregs.h.dl = (uchar)secno;         /* セクタ番号   */
  1493.     inregs.x.bx = seccnt;               /* セクタ数     */
  1494.     segregs.ds  = FP_SEG(buf1);
  1495.     inregs.x.di = FP_OFF(buf1);
  1496.     int86x(0x93, &inregs, &outregs, &segregs);
  1497.     *secnum = outregs.x.bx;
  1498.     ret = outregs.h.ah;
  1499.     if (ret == 0x80) {
  1500.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1501.     }
  1502.  
  1503.     return (ret);
  1504. }
  1505.  
  1506. /*-------------------------------------------------------------------*/
  1507. /* データの書き込み  (FD)                                            */
  1508. /*-------------------------------------------------------------------*/
  1509. int uDKB_write(int devno, int cylno, int headno, int secno, int seccnt,
  1510.               char *buf1, int *secnum)
  1511. {
  1512.     union  REGS  inregs, outregs;
  1513.     struct SREGS segregs;
  1514.     int    ret;
  1515.  
  1516.     inregs.h.ah = 0x06;                 /* 機能コード   */
  1517.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1518.     inregs.x.cx = cylno;                /* シリンダ番号 */
  1519.     inregs.h.dh = (uchar)headno;        /* ベッド番号   */
  1520.     inregs.h.dl = (uchar)secno;         /* セクタ番号   */
  1521.     inregs.x.bx = seccnt;               /* セクタ数     */
  1522.     segread(&segregs);
  1523.     inregs.x.di = FP_OFF(buf1);
  1524.     int86x(0x93, &inregs, &outregs, &segregs);
  1525.     *secnum = outregs.x.bx;
  1526.     ret = outregs.h.ah;
  1527.     if (ret == 0x80) {
  1528.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1529.     }
  1530.  
  1531.     return (ret);
  1532. }
  1533.  
  1534. /*-------------------------------------------------------------------*/
  1535. /* データの書き込み  (FD)                                            */
  1536. /*-------------------------------------------------------------------*/
  1537. int uDKB_write1(int devno, int cylno, int headno, int secno, int seccnt,
  1538.               char huge *buf1, int *secnum)
  1539. {
  1540.     union  REGS  inregs, outregs;
  1541.     struct SREGS segregs;
  1542.     int    ret;
  1543.  
  1544.     inregs.h.ah = 0x06;                 /* 機能コード   */
  1545.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1546.     inregs.x.cx = cylno;                /* シリンダ番号 */
  1547.     inregs.h.dh = (uchar)headno;        /* ベッド番号   */
  1548.     inregs.h.dl = (uchar)secno;         /* セクタ番号   */
  1549.     inregs.x.bx = seccnt;               /* セクタ数     */
  1550.     segregs.ds  = FP_SEG(buf1);
  1551.     inregs.x.di = FP_OFF(buf1);
  1552.     int86x(0x93, &inregs, &outregs, &segregs);
  1553.     *secnum = outregs.x.bx;
  1554.     ret = outregs.h.ah;
  1555.     if (ret == 0x80) {
  1556.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1557.     }
  1558.  
  1559.     return (ret);
  1560. }
  1561.  
  1562. /*-------------------------------------------------------------------*/
  1563. /*  セクタの検査  (FD)                                               */
  1564. /*-------------------------------------------------------------------*/
  1565. int uDKB_chksec(int devno, int cylno, int headno, int secno, int seccnt,
  1566.                 int *secnum)
  1567. {
  1568.     union  REGS  inregs, outregs;
  1569.     int    ret;
  1570.  
  1571.     inregs.h.ah = 0x07;                 /* 機能コード   */
  1572.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1573.     inregs.x.cx = cylno;                /* シリンダ番号 */
  1574.     inregs.h.dh = (uchar)headno;        /* ベッド番号   */
  1575.     inregs.h.dl = (uchar)secno;         /* セクタ番号   */
  1576.     inregs.x.bx = seccnt;               /* セクタ数     */
  1577.     int86(0x93, &inregs, &outregs);
  1578.     *secnum = outregs.x.bx;
  1579.     ret = outregs.h.ah;
  1580.     if (ret == 0x80) {
  1581.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1582.     }
  1583.  
  1584.     return (ret);
  1585. }
  1586.  
  1587. /*-------------------------------------------------------------------*/
  1588. /* セクタIDの取り出し  (FD)                                        */
  1589. /*-------------------------------------------------------------------*/
  1590. int uDKB_rdsecid(int devno, int cylno, int headno, DKB_SEC *secid)
  1591. {
  1592.     union  REGS  inregs, outregs;
  1593.     struct SREGS segregs;
  1594.     int    ret;
  1595.  
  1596.     inregs.h.ah = 0x09;                 /* 機能コード   */
  1597.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1598.     inregs.x.cx = cylno;                /*              */
  1599.     inregs.h.dh = (uchar)headno;        /*              */
  1600.     segread(&segregs);
  1601.     inregs.x.di = FP_OFF(secid);
  1602.     int86(0x93, &inregs, &outregs);
  1603.     ret = outregs.h.ah;
  1604.     if (ret == 0x80) {
  1605.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1606.     }
  1607.  
  1608.     return (ret);
  1609. }
  1610.  
  1611. /*-------------------------------------------------------------------*/
  1612. /* トラックのフォーマット  (FD)                                      */
  1613. /*-------------------------------------------------------------------*/
  1614. int uDKB_format(int devno, int cylno, int headno, uchar *buf1)
  1615. {
  1616.     union  REGS  inregs, outregs;
  1617.     struct SREGS segregs;
  1618.     int    ret;
  1619.  
  1620.     inregs.h.ah = 0x0A;                 /* 機能コード   */
  1621.     inregs.h.al = (uchar)devno;         /* デバイス番号 */
  1622.     inregs.x.cx = cylno;                /* シリンダ番号 */
  1623.     inregs.h.dh = (uchar)headno;        /* ベッド番号   */
  1624.     segread(&segregs);
  1625.     inregs.x.di = FP_OFF(buf1);
  1626.     int86x(0x93, &inregs, &outregs, &segregs);
  1627.     ret = outregs.h.ah;
  1628.     if (ret == 0x80) {
  1629.         ret = (outregs.h.ah << 8) | (outregs.x.cx & 0x00ff );
  1630.     }
  1631.  
  1632.     return (ret);
  1633. }
  1634.  
  1635. /*-------------------------------------------------------------------*/
  1636. /*  システム情報の取得                                               */
  1637. /*-------------------------------------------------------------------*/
  1638. int system_get(uchar *p)
  1639. {
  1640.     union  REGS  inregs, outregs;
  1641.     struct SREGS segregs;
  1642.     int    ret;
  1643.  
  1644.     inregs.h.ah = 0x00;                 /* 機能コード   */
  1645.     segread(&segregs);
  1646.     inregs.x.di = FP_OFF(p);
  1647.     int86x(0x8e, &inregs, &outregs, &segregs);
  1648.     ret = outregs.h.ah;
  1649.  
  1650.     return (ret);
  1651. }
  1652.